#pragma once

#include <cstdint>
#include<iostream>
#include<sys/epoll.h>
#include"Log.hpp"
#include"Common.hpp"
using namespace LogModule;

namespace EpollerModule
{
   
    class Epoller
    {
    public:
        Epoller():_epfd(-1)
        {}

        //创建epoll模型
        void Init()
        {
            
            _epfd = ::epoll_create(256);
            if(_epfd < 0)
            {
                LOG(LogLevel::ERROR) << "epoll_create error";
                exit(EPOLL_CREAT_ERR);
            }
            LOG(LogLevel::ERROR) << "epoll_create success :" << _epfd;
        }

        //epoll等待
        int Wait(struct epoll_event revs[],int num,int timeout)//输出就绪的fd和events
        {
            int n = ::epoll_wait(_epfd, revs, num, timeout);
            if(n < 0)
            {
                LOG(LogLevel::WARNING) << "epoll_wait error";
            }
            return n;
        }

        //epoll的相关操作（增删改）
        void Ctrl(int sockfd, uint32_t events, int flag)
        {
            struct epoll_event ev;
            ev.events = events;
            ev.data.fd = sockfd;
            int n = epoll_ctl(_epfd, flag, sockfd, &ev);
            if (n < 0)
            {
                LOG(LogLevel::WARNING) << "epoll_ctl error";
            }
        }
        //增
        void Add(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_ADD);
        }
        //删
        void Delete(int sockfd)
        {
            int n = ::epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);
            if (n < 0)
            {
                LOG(LogLevel::WARNING) << "epoll_ctl_del error";
            }
        }
        //改
        void Update(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_MOD);
        }

        ~Epoller()
        {}
        
    private:
        int _epfd;
    };
}